package com.xingkeduo.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.xingkeduo.dao.database.DatabaseAccessObject;
import com.xingkeduo.dao.database.DatabaseProxy;
import com.xingkeduo.util.pojo.base.BaseQuery;
import com.xingkeduo.util.pojo.base.BaseTable;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

@Configuration
@Conditional(MybatisPlusCondition.class)
public class MybatisPlusSqlSessionConfig<T extends BaseTable<T>, Q extends BaseQuery<Q>> {
	@Value("${db.mysql.order.driver}")
	private String driver;
	@Value("${db.mysql.order.url}")
	private String url;
	@Value("${db.mysql.order.user}")
	private String user;
	@Value("${db.mysql.order.password}")
	private String password;
	@Value("${db.mysql.order.maxActive}")
	private int maxActive;
	@Value("${db.mysql.order.initialSize}")
	private int initialSize;
	@Value("${db.mysql.order.maxWait}")
	private long maxWait;
	@Value("${db.mysql.order.minIdle}")
	private int minIdle;

	@Bean
    public DataSource initDataSource() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        dataSource.setFilters("stat");// 监控数据库
        dataSource.setMaxActive(maxActive);// 连接池最大使用连接数量
        dataSource.setInitialSize(initialSize);// 初始化连接大小
        dataSource.setMaxWait(maxWait);// 获取连接最大等待时间，单位是毫秒
        dataSource.setMinIdle(minIdle);// 连接池最小空闲连接数量
        dataSource.setTimeBetweenEvictionRunsMillis(60000);// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(300000);// 配置一个连接在池中最小生存的时间，单位是毫秒
        dataSource.setRemoveAbandoned(true);// 打开removeAbandoned功能
        dataSource.setRemoveAbandonedTimeout(1800);// removeAbandoned超时时间，单位是秒
        dataSource.setLogAbandoned(true);// 关闭abanded连接时输出错误日志
        dataSource.setValidationQuery("SELECT 'x'");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        dataSource.setPoolPreparedStatements(true);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(50);

        return dataSource;
    }



	@Bean(name = "mysqlUserTransactionManager")
	public DataSourceTransactionManager initTransactionManager(@Autowired DataSource dataSource) {
		try {
			return new DataSourceTransactionManager(dataSource);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}



	@Bean(name = "mysqlUserSqlSessionFactory")
	public SqlSessionFactory initSqlSessionFactory(@Autowired DataSource dataSource
			,@Autowired GlobalConfig mpGlobalConfig
			,@Autowired PaginationInterceptor paginationInterceptor
			,@Autowired OptimisticLockerInterceptor optimisticLoker)
			throws Exception {

		MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
		mybatisSqlSessionFactoryBean.setDataSource(dataSource);
		//enum映射
		mybatisSqlSessionFactoryBean.setTypeEnumsPackage("com.xingkeduo.pojo.enums");

		MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
		mybatisConfiguration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
		mybatisConfiguration.setMapUnderscoreToCamelCase(true);
		mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);


		mybatisSqlSessionFactoryBean.setGlobalConfig(mpGlobalConfig);

		mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[]{paginationInterceptor});
		//mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[]{optimisticLoker});

		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		mybatisSqlSessionFactoryBean.setTypeAliasesPackage("com.xingkeduo.pojo.table,com.xingkeduo.pojo.query");
		//开启mapper扫描
		mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
		mybatisSqlSessionFactoryBean.setVfs(SpringBootVFS.class);
		//mybatisSqlSessionFactoryBean.setConfigLocation(resolver.getResource("classpath:mybatis.xml"));

		return mybatisSqlSessionFactoryBean.getObject();
	}

	@Bean(name = "mysqlUserMasterSqlSessionTemplateFromMybatis")
	public SqlSessionTemplate initSqlSessionTemplate(
			@Qualifier("mysqlUserSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
		return new SqlSessionTemplate(sqlSessionFactory);
	}
/*
	@Bean(name = "mysqlUserMasterDao")
	public DatabaseAccessObject<T, Q> initMysqluserDao(
			@Qualifier("mysqlUserMasterSqlSessionTemplateFromMybatis") SqlSessionTemplate sqlSessionTemplate){
		return new DatabaseProxy<T, Q>().build(sqlSessionTemplate,null);
	}*/
}
